import win32api
import win32con
from time import sleep

class KeyboardController:
    def __init__(self):
        self.vk_code_map = {
            'backspace': 0x08,  # Backspace
            'tab': 0x09,        # Tab
            'enter': 0x0D,      # Enter
            'shift': 0x10,      # Shift
            'ctrl': 0x11,       # Ctrl
            'alt': 0x12,        # Alt
            'pause': 0x13,      # Pause
            'capslock': 0x14,   # Caps Lock
            'esc': 0x1B,        # Escape
            'space': 0x20,      # Space
            'pageup': 0x21,     # Page Up
            'pagedown': 0x22,   # Page Down
            'end': 0x23,        # End
            'home': 0x24,       # Home
            'leftarrow': 0x25,  # Left Arrow
            'uparrow': 0x26,    # Up Arrow
            'rightarrow': 0x27, # Right Arrow
            'downarrow': 0x28,  # Down Arrow
            'insert': 0x2D,     # Insert
            'delete': 0x2E,     # Delete
            '0': 0x30,          # 0
            '1': 0x31,          # 1
            '2': 0x32,          # 2
            '3': 0x33,          # 3
            '4': 0x34,          # 4
            '5': 0x35,          # 5
            '6': 0x36,          # 6
            '7': 0x37,          # 7
            '8': 0x38,          # 8
            '9': 0x39,          # 9
            'a': 0x41,          # A
            'b': 0x42,          # B
            'c': 0x43,          # C
            'd': 0x44,          # D
            'e': 0x45,          # E
            'f': 0x46,          # F
            'g': 0x47,          # G
            'h': 0x48,          # H
            'i': 0x49,          # I
            'j': 0x4A,          # J
            'k': 0x4B,          # K
            'l': 0x4C,          # L
            'm': 0x4D,          # M
            'n': 0x4E,          # N
            'o': 0x4F,          # O
            'p': 0x50,          # P
            'q': 0x51,          # Q
            'r': 0x52,          # R
            's': 0x53,          # S
            't': 0x54,          # T
            'u': 0x55,          # U
            'v': 0x56,          # V
            'w': 0x57,          # W
            'x': 0x58,          # X
            'y': 0x59,          # Y
            'z': 0x5A,          # Z
            'lwin': 0x5B,       # Left Windows Key
            'rwin': 0x5C,       # Right Windows Key
            'numpad0': 0x60,    # NumPad 0
            'numpad1': 0x61,    # NumPad 1
            'numpad2': 0x62,    # NumPad 2
            'numpad3': 0x63,    # NumPad 3
            'numpad4': 0x64,    # NumPad 4
            'numpad5': 0x65,    # NumPad 5
            'numpad6': 0x66,    # NumPad 6
            'numpad7': 0x67,    # NumPad 7
            'numpad8': 0x68,    # NumPad 8
            'numpad9': 0x69,    # NumPad 9
            'multiply': 0x6A,   # Multiply (*)
            'add': 0x6B,        # Add (+)
            'separator': 0x6C,  # Separator (,)
            'subtract': 0x6D,   # Subtract (-)
            'decimal': 0x6E,    # Decimal (.)
            'divide': 0x6F,     # Divide (/)
            'f1': 0x70,         # F1
            'f2': 0x71,         # F2
            'f3': 0x72,         # F3
            'f4': 0x73,         # F4
            'f5': 0x74,         # F5
            'f6': 0x75,         # F6
            'f7': 0x76,         # F7
            'f8': 0x77,         # F8
            'f9': 0x78,         # F9
            'f10': 0x79,        # F10
            'f11': 0x7A,        # F11
            'f12': 0x7B,        # F12
            'numlock': 0x90,    # Num Lock
            'scrolllock': 0x91, # Scroll Lock
            'semicolon': 0xBA,  # ; (Semicolon)
            'equals': 0xBB,     # = (Equals)
            'comma': 0xBC,      # , (Comma)
            'dash': 0xBD,       # - (Dash)
            'period': 0xBE,     # . (Period)
            'slash': 0xBF,      # / (Slash)
            'grave': 0xC0,      # ` (Grave Accent)
        }

    def press_key(self,key_name,delay=0.05):
        """
        按下指定的键
        :param key_name: 键的名称或虚拟键码
        :param delay: 延迟时间
        :return: None
        """
        if isinstance(key_name, str):
            key = self.vk_code_map.get(key_name.lower())
            if key is None:
                raise ValueError(f"无效的键名: {key_name}")
        elif isinstance(key_name, int):
            key = key_name
        win32api.keybd_event(key, 0, 0, 0)
        sleep(delay)
        win32api.keybd_event(key, 0, win32con.KEYEVENTF_KEYUP, 0)

    def key_down(self,key_name,delay=0.05):
        """
        按下指定的键
        :param key_name: 键的名称或虚拟键码
        :param delay: 延迟时间
        :return: None
        """
        if isinstance(key_name, str):
            key = self.vk_code_map.get(key_name.lower())
            if key is None:
                raise ValueError(f"无效的键名: {key_name}")
        elif isinstance(key_name, int):
            key = key_name
        win32api.keybd_event(key, 0, 0, 0)
        sleep(delay)

    def key_up(self,key_name,delay=0.05):
        """
        释放指定的键
        :param key_name: 键的名称或虚拟键码
        :param delay: 延迟时间
        :return: None
        """
        if isinstance(key_name, str):
            key = self.vk_code_map.get(key_name.lower())
            if key is None:
                raise ValueError(f"无效的键名: {key_name}")
        elif isinstance(key_name, int):
            key = key_name
        win32api.keybd_event(key, 0, win32con.KEYEVENTF_KEYUP, 0)
        sleep(delay)
